package com.csii.user.aspect;

import cn.hutool.json.JSONUtil;
import com.csii.core.constant.CommonConstant;
import com.csii.core.util.IPUtils;
import com.csii.core.util.SpringContextUtils;
import com.csii.core.util.TenantContext;
import com.csii.log.model.Audit;
import com.csii.log.service.IAuditService;
import com.csii.user.entity.SysUser;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.io.UnsupportedEncodingException;
import java.time.LocalDateTime;
import java.util.Base64;


/**
 * 系统日志，切面处理类
 *
 * @Author ian
 * @email yangyang@csiisz.com
 * @Date 2018年1月14日
 */
@Slf4j
@Aspect
@Component
public class LoginAndLogoutLogAspect {

    @Autowired
    private IAuditService auditService;
    @Value("${spring.application.name}")
    private String applicationName;


	@Pointcut("execution(* com.csii.security.authentication.CustomAuthenticationSuccessHandler.onAuthenticationSuccess(..))")
	public void loginPointCut() {

	}

    @Pointcut("execution(* com.csii.security.authentication.session.CustomLogoutHandler.logout(..))")
    public void logoutPointCut() {

    }

	@Around("loginPointCut()")
	public Object loginAround(ProceedingJoinPoint point) throws Throwable {
		long beginTime = System.currentTimeMillis();
		//执行方法
		Object result = point.proceed();
		//执行时长(毫秒)
		long time = System.currentTimeMillis() - beginTime;

		//保存日志
		saveSysLog(time,",登录成功！",getLoginUser());

		return result;
	}

    @Around("logoutPointCut()")
    public Object logoutAround(ProceedingJoinPoint point) throws Throwable {
        long beginTime = System.currentTimeMillis();
        SysUser loginUser = getLoginUser();
        //执行方法
        Object result = point.proceed();
        //执行时长(毫秒)
        long time = System.currentTimeMillis() - beginTime;
        if (loginUser != null){
            //保存日志
            saveSysLog(time,",退出成功！",loginUser);
        }
        return result;
    }

    private SysUser getLoginUser(){
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        return authentication == null ? null : (SysUser) authentication.getPrincipal();
    }

	private void saveSysLog(long time,String logContent,SysUser sysUser ) {
        if(sysUser!=null){
            Audit sysLog = new Audit();
            sysLog.setLogType(CommonConstant.LOG_TYPE_1);
            try {
                //获取request
                HttpServletRequest request = SpringContextUtils.getHttpServletRequest();
                //设置IP地址
                sysLog.setIp(IPUtils.getIpAddr(request));
            } catch (Exception e) {
                sysLog.setIp("127.0.0.1");
            }
            sysLog.setUserId(sysUser.getId());
            sysLog.setUserName(sysUser.getUsername());
            sysLog.setOperation("用户名: " + sysLog.getUserName() + logContent);
            sysLog.setCostTime(time);
            sysLog.setTimestamp(LocalDateTime.now());
            sysLog.setApplicationName(applicationName);
            sysLog.setTenantId(TenantContext.getTenant());
            sysLog.setOperateType(CommonConstant.LOG_TYPE_1);
            ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            HttpServletRequest request = attributes.getRequest();
            sysLog.setIp(IPUtils.getIpAddr(request));
            //保存系统日志
            try {
                String userinfo = Base64.getEncoder().encodeToString(JSONUtil.toJsonStr(sysUser).getBytes("utf-8"));
                sysLog.setParams(userinfo);
                auditService.save(sysLog);
            } catch (UnsupportedEncodingException e) {
                log.error("userInfo 编码转换异常",e);
            }

        }
	}

}
